package com.zl.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zl.NotFoundException;
import com.zl.dao.BlogRepository;
import com.zl.entity.po.t_Blog;
import com.zl.entity.po.t_Blog_Tags;
import com.zl.entity.po.t_Blog_TagsExample;
import com.zl.entity.povo.Blog;
import com.zl.entity.povo.Tag;
import com.zl.entity.povo.Type;
import com.zl.entity.povo.User;
import com.zl.mapper.t_BlogMapper;
import com.zl.mapper.t_Blog_TagsMapper;
import com.zl.mapper.t_CommentMapper;
import com.zl.mapper.t_TagMapper;
import com.zl.service.BlogService;
import com.zl.util.MarkdownUtils;
import com.zl.util.MyBeanUtils;
import com.zl.vo.BlogQuery;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by limi on 2017/10/20.
 */
@Service
@Log4j
public class BlogServiceImpl implements BlogService {


    @Autowired
    private BlogRepository blogRepository;
    @Autowired
    private t_BlogMapper blogMapper;
    @Autowired
    private t_CommentMapper tCommentMapper;
    @Autowired
    private t_Blog_TagsMapper t_blog_tagsMapper;
    @Autowired
    private t_TagMapper tagMapper;

    /**
     * 获取博客数据编辑博客
     * @param id
     * @return
     */
    @Override
    public Blog getBlog(Long id) {
        // return blogRepository.findOne(id);
        /**
         * 两步操作
         * 1.通过关联查询获取blog,type,user,是一对一的关系直接关联查询
         * 2,tag单独查询通过blog_tag和tag关联多对多的关系
         */
        Blog blog = blogMapper.selectBlogById(id);
        Type  type = blogMapper.getBlogByTypeId(id);
        List<Tag> tags =t_blog_tagsMapper.selectTagByUserId(id);
        blog.setTags(tags);
        blog.setType(type);
        return blog;
    }

    @Transactional
    @Override
    public Blog getAndConvert(Long id) {
        // Blog blog = blogRepository.findOne(id);
        Blog blog = blogMapper.selectBlogById(id);
        if (blog == null) {
            throw new NotFoundException("该博客不存在");
        }
        Blog b = new Blog();
        BeanUtils.copyProperties(blog,b);
        String content = b.getContent();
        b.setContent(MarkdownUtils.markdownToHtmlExtensions(content));
        log.info("变换浏览次数与");
        // blogRepository.updateViews(id);
        try {
            blogMapper.updateViews(id);
        } catch (Exception e) {
            log.error("增加浏览次数错误 {}",e);
        }
        log.info("变换浏览次数与");

        return b;
    }

    /**
     * 获取后台自己博客列表
     * @param pageNum
     * @param user
     * @return
     */
    @Override
    public PageInfo<Blog> listBlog(Integer pageNum,Long id) {
            PageHelper.startPage(pageNum,8);
            List<Blog> blogs = blogMapper.selectAllByTypeId(id);
            for (Blog blog1 : blogs) {
                List<Tag> tagByBlogId = tagMapper.getTagByBlogId(blog1.getId());
                blog1.setTags(tagByBlogId);
            }
            PageInfo<Blog> pageInfo = new PageInfo<>(blogs);
            return pageInfo;

    }

    @Override
    public PageInfo<Blog> listBlog(Integer pageNum) {
        PageHelper.startPage(pageNum,6);
        List<Blog> blogs = blogMapper.selectAll();
        for (Blog blog : blogs) {
            List<Tag> tagByBlogId = tagMapper.getTagByBlogId(blog.getId());
            blog.setTags(tagByBlogId);
        }
        PageInfo pageInfo = new PageInfo(blogs);
        return pageInfo;
    }

    /**
     * 通过标签获取相应的博客列表
     * @param tagId
     * @param pageNum
     * @return
     */
    @Override
    public PageInfo<Blog> listBlog(Long tagId, Integer pageNum) {
        PageHelper.startPage(pageNum,6);
        List<Blog> blogs = blogMapper.selectByTagId(tagId);
        for (Blog blog : blogs) {
            List<Tag> tags = tagMapper.getTagByBlogId(blog.getId());
            blog.setTags(tags);
        }
        PageInfo<Blog> pageInfo = new PageInfo(blogs);
        return pageInfo;
    }

    @Override
    public PageInfo<Blog> listBlog(String query, Integer pageaNum) {
        // return blogRepository.findByQuery(query,pageable);
        PageHelper.startPage(pageaNum,7);
        List<Blog> blogs = blogMapper.selectByQuery(query);
        for (Blog blog : blogs) {
            List<Tag> tags = tagMapper.getTagByBlogId(blog.getId());
            blog.setTags(tags);
        }
        PageInfo<Blog> pageInfo = new PageInfo(blogs);
        return pageInfo;
    }

    @Override
    public List<Blog> listRecommendBlogTop(Integer size) {
        // Sort sort = new Sort(Sort.Direction.DESC,"updateTime");
        // Pageable pageable = new PageRequest(0, size, sort);
        // return blogRepository.findTop(pageable);
        PageHelper.startPage(1,size);
        List<Blog> blogs = blogMapper.selectAll();
        PageInfo<Blog> pageInfo = new PageInfo(blogs);
        return pageInfo.getList();
    }

    /**
     * 获取历史档案
     * @return
     */
    @Override
    public Map<String, List<Blog>> archiveBlog() {
        List<String> years = blogRepository.findGroupYear();
        Map<String, List<Blog>> map = new HashMap<>();
        for (String year : years) {
            map.put(year, blogRepository.findByYear(year));
        }
        return map;
    }

    /**
     * 获取博客数量
     * @return
     */
    @Override
    public Long countBlog() {
        // return blogRepository.count();
        return blogMapper.getNum();
    }

    /**
     * 保存博客
     * @param blog
     * @return
     */
    @Transactional
    @Override
    public Blog saveBlog(Blog blog) {
        if (blog.getId() == null) {
            blog.setCreateTime(new Date());
            blog.setUpdateTime(new Date());
            blog.setViews(0);
            log.info("首次发布或者保存草稿");
            return saveBlogNotId(blog);
        } else {
            blog.setUpdateTime(new Date());
            return updateBlog(blog.getId(),blog);
        }
        // return blogRepository.save(blog);
    }

    /**
     * 保存博客没有id
     * @param blog
     * @return
     */
    private Blog saveBlogNotId(Blog blog) {
        //插入blog
        t_Blog t_blog =new t_Blog();
        BeanUtils.copyProperties(blog,t_blog);
        t_blog.setUserId(blog.getUser().getId());
        t_blog.setTypeId(blog.getType().getId());
        long key = blogMapper.insert(t_blog);
        //获取标签
        List<Tag> tagList = blog.getTags();
        for (Tag tag : tagList) {
            t_Blog_Tags t_blog_tags = new t_Blog_Tags();
            t_blog_tags.setTagsId(tag.getId());
            t_blog_tags.setBlogsId(key);
            t_blog_tagsMapper.insertSelective(t_blog_tags);
        }
        blog.setId(key);
        return blog;

    }

    /**
     * 更新博客
     * @param id
     * @param blog
     * @return
     */
    @Transactional
    @Override
    public Blog updateBlog(Long id, Blog blog) {
        // Blog b = blogRepository.findOne(id);
        t_Blog t_blog = blogMapper.selectByPrimaryKey(id);
        if (t_blog == null) {
            throw new NotFoundException("该博客不存在");
        }
        // Blog blog1 = new Blog();
        // BeanUtils.copyProperties(t_blog,blog1);
        BeanUtils.copyProperties(blog, t_blog, MyBeanUtils.getNullPropertyNames(blog));
        t_blog.setUpdateTime(new Date());
        t_blog.setTypeId(blog.getType().getId());
        t_blog.setUserId(blog.getUser().getId());
        t_blog.setUpdateTime(new Date());
        // return blogRepository.save(blog);
        /**
         * 更新blog表,tag_blog表
         */
        // blogMapper.updateByPrimaryKeySelective(t_blog);
        t_Blog_TagsExample t_blog_tagsExample = new t_Blog_TagsExample();
        t_blog_tagsExample.createCriteria().andBlogsIdEqualTo(id);
        try {
            t_blog_tagsMapper.deleteByExample(t_blog_tagsExample);
        } catch (Exception e) {
            log.error("更新博客数据,删除标签异常!");
            e.printStackTrace();
        }
        List<Tag> tags = blog.getTags();
        for (Tag tag : tags) {
            t_Blog_Tags t_blog_tags = new t_Blog_Tags();
            t_blog_tags.setBlogsId(id);
            t_blog_tags.setTagsId(tag.getId());
            try {
                t_blog_tagsMapper.insert(t_blog_tags);
            } catch (Exception e) {
                log.error("更新博客,插入标签异常");
                e.printStackTrace();
            }
        }
        try {
            blogMapper.updateByPrimaryKeySelective(t_blog);
        } catch (Exception e) {
            log.error("更新博客,更新博客异常");
            e.printStackTrace();
        }
        return blog;

    }

    /**
     * 删除博客
     * @param id
     */
    @Transactional
    @Override
    public void deleteBlog(Long id) {
        // blogMapper.deleteByPrimaryKey(id);
        log.info("删除开始");
        // blogRepository.delete(id);
        blogMapper.deleteTagById(id);
        long num = tCommentMapper.selectByBlogId(id);
        if (num > 0) {
            blogMapper.deleteCommentById(id);
        }
        blogMapper.deleteBlogById(id);
        log.info("删除结束");
    }

    @Override
    public PageInfo<Blog> listBlog(Integer pageNum, BlogQuery blog, User user) {
        PageHelper.startPage(pageNum,8);
        List<Blog> blogs = blogMapper.selectAllByAdmin(user,blog);
        for (Blog blog1 : blogs) {
            List<Tag> tagByBlogId = tagMapper.getTagByBlogId(blog1.getId());
            blog1.setTags(tagByBlogId);
        }
        PageInfo<Blog> pageInfo = new PageInfo<>(blogs);
        return pageInfo;

    }
}
